/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.kylingroup.Desktop.Plugin.FileUploader;

import com.kylingroup.Desktop.Plugin.FileUploader.Bean.FileTreeItem;
import com.kylingroup.Desktop.Plugin.FileUploader.Utils.DirectoryIterator;
import com.kylingroup.Desktop.Plugin.FileUploader.Cell.FileTreeCell;
import com.kylingroup.Desktop.Plugin.FileUploader.Flat.FlatView;
import com.kylingroup.Desktop.Plugin.FileUploader.Flat.LocalFlatView;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.ResourceBundle;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.SingleSelectionModel;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.effect.Effect;
import javafx.scene.effect.MotionBlur;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.stage.DirectoryChooser;
import javafx.stage.Modality;
import javafx.util.Callback;

/**
 * FXML Controller class
 *
 * @author kylin
 */
public class FileuploaderController implements Initializable {
    @FXML
    private ImageView btnOpen;
    @FXML
    private TextField txtSourcepath;
    @FXML
    private TextField txtfilter;
    @FXML
    private CheckBox checkdel;
    @FXML
    private TreeView<FileTreeItem> fileTree;
    @FXML
    private VBox infobox;
    @FXML
    private Label lbfilename,lbfilesize,lbfiletype,lbfilepath;
    @FXML
    private ProgressBar openprogress;
    @FXML
    private ComboBox servers;
    @FXML
    private VBox flatviewbox;
    
    private HashMap<String,Node> fileInfoNodes;
    
    public static boolean delemode=false;
    public static HashMap<String,Image> typeicons=null;
    
    @Override
    public void initialize(URL url, ResourceBundle rb){
        
        //System.out.println("initialize uploader:"+txtSourcepath.toString());
        txtSourcepath.setEditable(false);
        initTypeIconMap();
        
        initInfoBox();
       
        initServers();
        
        MotionBlur motionBlur = new MotionBlur();
        motionBlur.setRadius(3.2);
        motionBlur.setAngle(92.1);
        setImageButton(btnOpen,"openDir", motionBlur);
       
        checkdel.selectedProperty().addListener(new ChangeListener(){
            @Override
            public void changed(ObservableValue observable, Object oldValue, Object newValue) {
                delemode=Boolean.parseBoolean(newValue.toString());
            }
        });
        
        txtfilter.setOnAction(new EventHandler<ActionEvent>(){
            @Override
            public void handle(ActionEvent event) {
                if(txtSourcepath.getText()!=null&&!txtSourcepath.getText().equalsIgnoreCase("")){
                    createTree(txtSourcepath.getText(),txtfilter.getText().toLowerCase().trim());
                }else{
                    alert("Path should not be null.");
                }
            }
        });
    }
//**************************************************************************************************************
    private void alert(String info){
        Alert alert=new Alert(Alert.AlertType.WARNING,"");
        alert.initModality(Modality.APPLICATION_MODAL);
        alert.initOwner(null);
        alert.getDialogPane().setContentText(info);
        alert.getDialogPane().setHeaderText(Alert.AlertType.WARNING.name());
        alert.showAndWait().filter(response -> response==ButtonType.OK).ifPresent(response -> System.out.println("The alert was approved"));
    }
//**************************************************************************************************************
    public void initTypeIconMap(){
        typeicons=new HashMap<String,Image>();
        String sourcepath=System.getProperty("user.dir");
        File sourcefolder=new File(sourcepath+"/resources/icons");
        File files[]=sourcefolder.listFiles();
        
        for(int i=0;i<files.length;i++){
            String type=files[i].getName();
            type=type.substring(0,type.lastIndexOf("."));
            type=type.toLowerCase();
            Image img=new Image("file:"+files[i].getAbsolutePath());
            typeicons.put(type, img);
        }
    }
    public void initInfoBox(){
       fileInfoNodes=new HashMap<String,Node>();
       fileInfoNodes.put("infobox",infobox);
       fileInfoNodes.put("filename",lbfilename);
       fileInfoNodes.put("filetype",lbfiletype);
       fileInfoNodes.put("filesize",lbfilesize);
       fileInfoNodes.put("filepath",lbfilepath);
    }
    
    public void openDir(){
        DirectoryChooser chooser=new DirectoryChooser();
        chooser.setTitle("Select a extract directory");
        chooser.setInitialDirectory(new File(System.getProperty("user.home")));
        File sourcedir=chooser.showDialog(null);
        if(sourcedir!=null&&sourcedir.exists()){
            txtSourcepath.setText(sourcedir.getAbsolutePath());
            txtSourcepath.setEditable(false);
            resetInfoBox();
            createTree(sourcedir.getAbsolutePath(),"");
        }else{}
    }
    
    public void createTree(String path,String filter){
        FileTreeItem rootItem=new FileTreeItem();
        File rootFile=new File(path);
        rootItem.setFile(rootFile);
        rootItem.setFileInfoNodes(fileInfoNodes);
        
        TreeItem<FileTreeItem> treeRoot=new TreeItem<FileTreeItem>(rootItem);

        treeRoot.setExpanded(true);
        fileTree.setRoot(treeRoot);
        fileTree.setCellFactory(new Callback<TreeView<FileTreeItem>,TreeCell<FileTreeItem>>(){
            @Override
            public TreeCell<FileTreeItem> call(TreeView<FileTreeItem> param) {
                return new FileTreeCell();
            }
        });
        fileTree.setShowRoot(true);
        DirectoryIterator itor=new DirectoryIterator(treeRoot,fileInfoNodes);
        itor.start(rootFile.getAbsolutePath(),filter);
    }
    
    private void resetInfoBox(){
        infobox.setVisible(false);
        lbfilename.setText("");
        lbfiletype.setText("");
        lbfilesize.setText("");
        lbfilepath.setText("");
    }
//**************************************************************************************************************
    private void initServers(){
        ArrayList<String> datas=new ArrayList<String>();
        datas.add("local");
        datas.add("qinit");
        datas.add("baidu");
        servers.getItems().addAll(datas);
        
        SingleSelectionModel model=servers.getSelectionModel();
        model.selectedItemProperty().addListener(new ChangeListener(){
            @Override
            public void changed(ObservableValue observable, Object oldValue, Object newValue) {
                
                if(model.getSelectedItem().equals("local")){
                    String homedir="/media/kylin/My Passport";
                    createFlatPane(homedir);
                }else{
                    flatviewbox.getChildren().removeAll(flatviewbox.getChildren());
                }
            }        
        });
    }
    
    private void createFlatPane(String path){
        FlatView view=new LocalFlatView(flatviewbox);
        view.show(path);
        //HashMap<String,Integer> position=view.iterator(path);
    }
//***************************************************************************************************************
    public void setImageButton(ImageView btn,String method,Effect effect){
        btn.setOnMouseClicked(new EventHandler<MouseEvent>(){
            @Override
            public void handle(MouseEvent event) {
                try {
                    FileuploaderController.this.getClass().getDeclaredMethod(method, null).invoke(FileuploaderController.this, null);//.this.getClass().getDeclaredMethod(method).invoke(FileBrowserController.this);
                } catch (IllegalAccessException ex) {
                    ex.printStackTrace();
                } catch (IllegalArgumentException ex) {
                    ex.printStackTrace();
                } catch (InvocationTargetException ex) {
                    ex.printStackTrace();
                } catch (NoSuchMethodException ex) {
                    ex.printStackTrace();
                } catch (SecurityException ex) {
                    ex.printStackTrace();
                }
            }
        });
        if(effect!=null){
            btn.setOnMouseEntered(new EventHandler<MouseEvent>(){
                @Override
                public void handle(MouseEvent event) {
                    btn.setEffect(effect);
                }
            });
            btn.setOnMouseExited(new EventHandler<MouseEvent>(){
                @Override
                public void handle(MouseEvent event) {
                    btn.setEffect(null);
                }
            });
        }
    }
}
